/*
Copyright (c) 2015, Cisco Systems
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdlib.h>
#include <assert.h>
#include <memory.h>
#include "global.h"
#include "transform.h"
#include "common_block.h"
#include "common_kernels.h"
#include "simd.h"
#include <stdio.h>

static const int16_t g1mat_hevc[4][4] = {
  { 64, 64, 64, 64},
  { 83, 36,-36,-83},
  { 64,-64,-64, 64},
  { 36,-83, 83,-36}
};

static const int16_t g2mat_hevc[8][8] = {
  { 64, 64, 64, 64, 64, 64, 64, 64},
  { 89, 75, 50, 18,-18,-50,-75,-89},
  { 83, 36,-36,-83,-83,-36, 36, 83},
  { 75,-18,-89,-50, 50, 89, 18,-75},
  { 64,-64,-64, 64, 64,-64,-64, 64},
  { 50,-89, 18, 75,-75,-18, 89,-50},
  { 36,-83, 83,-36,-36, 83,-83, 36},
  { 18,-50, 75,-89, 89,-75, 50,-18}
};

static const int16_t g3mat_hevc[16][16] = {
  { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
  { 90, 87, 80, 70, 57, 43, 25,  9, -9,-25,-43,-57,-70,-80,-87,-90},
  { 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89},
  { 87, 57,  9,-43,-80,-90,-70,-25, 25, 70, 90, 80, 43, -9,-57,-87},
  { 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83},
  { 80,  9,-70,-87,-25, 57, 90, 43,-43,-90,-57, 25, 87, 70, -9,-80},
  { 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75},
  { 70,-43,-87,  9, 90, 25,-80,-57, 57, 80,-25,-90, -9, 87, 43,-70},
  { 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64},
  { 57,-80,-25, 90, -9,-87, 43, 70,-70,-43, 87,  9,-90, 25, 80,-57},
  { 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50},
  { 43,-90, 57, 25,-87, 70,  9,-80, 80, -9,-70, 87,-25,-57, 90,-43},
  { 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36},
  { 25,-70, 90,-80, 43,  9,-57, 87,-87, 57, -9,-43, 80,-90, 70,-25},
  { 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18},
  {  9,-25, 43,-57, 70,-80, 87,-90, 90,-87, 80,-70, 57,-43, 25, -9}
};

const int16_t g4mat_hevc[32][32] = {
  { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
  { 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13,  4, -4,-13,-22,-31,-38,-46,-54,-61,-67,-73,-78,-82,-85,-88,-90,-90},
  { 90, 87, 80, 70, 57, 43, 25,  9, -9,-25,-43,-57,-70,-80,-87,-90,-90,-87,-80,-70,-57,-43,-25, -9,  9, 25, 43, 57, 70, 80, 87, 90},
  { 90, 82, 67, 46, 22, -4,-31,-54,-73,-85,-90,-88,-78,-61,-38,-13, 13, 38, 61, 78, 88, 90, 85, 73, 54, 31,  4,-22,-46,-67,-82,-90},
  { 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89, 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89},
  { 88, 67, 31,-13,-54,-82,-90,-78,-46, -4, 38, 73, 90, 85, 61, 22,-22,-61,-85,-90,-73,-38,  4, 46, 78, 90, 82, 54, 13,-31,-67,-88},
  { 87, 57,  9,-43,-80,-90,-70,-25, 25, 70, 90, 80, 43, -9,-57,-87,-87,-57, -9, 43, 80, 90, 70, 25,-25,-70,-90,-80,-43,  9, 57, 87},
  { 85, 46,-13,-67,-90,-73,-22, 38, 82, 88, 54, -4,-61,-90,-78,-31, 31, 78, 90, 61,  4,-54,-88,-82,-38, 22, 73, 90, 67, 13,-46,-85},
  { 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83},
  { 82, 22,-54,-90,-61, 13, 78, 85, 31,-46,-90,-67,  4, 73, 88, 38,-38,-88,-73, -4, 67, 90, 46,-31,-85,-78,-13, 61, 90, 54,-22,-82},
  { 80,  9,-70,-87,-25, 57, 90, 43,-43,-90,-57, 25, 87, 70, -9,-80,-80, -9, 70, 87, 25,-57,-90,-43, 43, 90, 57,-25,-87,-70,  9, 80},
  { 78, -4,-82,-73, 13, 85, 67,-22,-88,-61, 31, 90, 54,-38,-90,-46, 46, 90, 38,-54,-90,-31, 61, 88, 22,-67,-85,-13, 73, 82,  4,-78},
  { 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75, 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75},
  { 73,-31,-90,-22, 78, 67,-38,-90,-13, 82, 61,-46,-88, -4, 85, 54,-54,-85,  4, 88, 46,-61,-82, 13, 90, 38,-67,-78, 22, 90, 31,-73},
  { 70,-43,-87,  9, 90, 25,-80,-57, 57, 80,-25,-90, -9, 87, 43,-70,-70, 43, 87, -9,-90,-25, 80, 57,-57,-80, 25, 90,  9,-87,-43, 70},
  { 67,-54,-78, 38, 85,-22,-90,  4, 90, 13,-88,-31, 82, 46,-73,-61, 61, 73,-46,-82, 31, 88,-13,-90, -4, 90, 22,-85,-38, 78, 54,-67},
  { 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64},
  { 61,-73,-46, 82, 31,-88,-13, 90, -4,-90, 22, 85,-38,-78, 54, 67,-67,-54, 78, 38,-85,-22, 90,  4,-90, 13, 88,-31,-82, 46, 73,-61},
  { 57,-80,-25, 90, -9,-87, 43, 70,-70,-43, 87,  9,-90, 25, 80,-57,-57, 80, 25,-90,  9, 87,-43,-70, 70, 43,-87, -9, 90,-25,-80, 57},
  { 54,-85, -4, 88,-46,-61, 82, 13,-90, 38, 67,-78,-22, 90,-31,-73, 73, 31,-90, 22, 78,-67,-38, 90,-13,-82, 61, 46,-88,  4, 85,-54},
  { 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50, 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50},
  { 46,-90, 38, 54,-90, 31, 61,-88, 22, 67,-85, 13, 73,-82,  4, 78,-78, -4, 82,-73,-13, 85,-67,-22, 88,-61,-31, 90,-54,-38, 90,-46},
  { 43,-90, 57, 25,-87, 70,  9,-80, 80, -9,-70, 87,-25,-57, 90,-43,-43, 90,-57,-25, 87,-70, -9, 80,-80,  9, 70,-87, 25, 57,-90, 43},
  { 38,-88, 73, -4,-67, 90,-46,-31, 85,-78, 13, 61,-90, 54, 22,-82, 82,-22,-54, 90,-61,-13, 78,-85, 31, 46,-90, 67,  4,-73, 88,-38},
  { 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36},
  { 31,-78, 90,-61,  4, 54,-88, 82,-38,-22, 73,-90, 67,-13,-46, 85,-85, 46, 13,-67, 90,-73, 22, 38,-82, 88,-54, -4, 61,-90, 78,-31},
  { 25,-70, 90,-80, 43,  9,-57, 87,-87, 57, -9,-43, 80,-90, 70,-25,-25, 70,-90, 80,-43, -9, 57,-87, 87,-57,  9, 43,-80, 90,-70, 25},
  { 22,-61, 85,-90, 73,-38, -4, 46,-78, 90,-82, 54,-13,-31, 67,-88, 88,-67, 31, 13,-54, 82,-90, 78,-46,  4, 38,-73, 90,-85, 61,-22},
  { 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18, 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18},
  { 13,-38, 61,-78, 88,-90, 85,-73, 54,-31,  4, 22,-46, 67,-82, 90,-90, 82,-67, 46,-22, -4, 31,-54, 73,-85, 90,-88, 78,-61, 38,-13},
  {  9,-25, 43,-57, 70,-80, 87,-90, 90,-87, 80,-70, 57,-43, 25, -9, -9, 25,-43, 57,-70, 80,-87, 90,-90, 87,-80, 70,-57, 43,-25,  9},
  {  4,-13, 22,-31, 38,-46, 54,-61, 67,-73, 78,-82, 85,-88, 90,-90, 90,-90, 88,-85, 82,-78, 73,-67, 61,-54, 46,-38, 31,-22, 13, -4}
};

static const int16_t g5mat_hevc[64][64] = {
#if 1
    {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
    {91, 90, 90, 89, 88, 87, 86, 84, 83, 81, 79, 76, 74, 71, 69, 66, 62, 59, 56, 52, 48, 45, 41, 37, 33, 28, 24, 20, 16, 11,  7,  2, -2, -7,-11,-16,-20,-24,-28,-33,-37,-41,-45,-48,-52,-56,-59,-62,-66,-69,-71,-74,-76,-79,-81,-83,-84,-86,-87,-88,-89,-90,-90,-91},
    {90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13,  4, -4,-13,-22,-31,-38,-46,-54,-61,-67,-73,-78,-82,-85,-88,-90,-90,-90,-90,-88,-85,-82,-78,-73,-67,-61,-54,-46,-38,-31,-22,-13, -4,  4, 13, 22, 31, 38, 46, 54, 61, 67, 73, 78, 82, 85, 88, 90, 90},
    {90, 88, 84, 79, 71, 62, 52, 41, 28, 16,  2,-11,-24,-37,-48,-59,-69,-76,-83,-87,-90,-91,-89,-86,-81,-74,-66,-56,-45,-33,-20, -7,  7, 20, 33, 45, 56, 66, 74, 81, 86, 89, 91, 90, 87, 83, 76, 69, 59, 48, 37, 24, 11, -2,-16,-28,-41,-52,-62,-71,-79,-84,-88,-90},
    {90, 87, 80, 70, 57, 43, 25,  9, -9,-25,-43,-57,-70,-80,-87,-90,-90,-87,-80,-70,-57,-43,-25, -9,  9, 25, 43, 57, 70, 80, 87, 90, 90, 87, 80, 70, 57, 43, 25,  9, -9,-25,-43,-57,-70,-80,-87,-90,-90,-87,-80,-70,-57,-43,-25, -9,  9, 25, 43, 57, 70, 80, 87, 90},
    {90, 84, 74, 59, 41, 20, -2,-24,-45,-62,-76,-86,-90,-89,-83,-71,-56,-37,-16,  7, 28, 48, 66, 79, 87, 91, 88, 81, 69, 52, 33, 11,-11,-33,-52,-69,-81,-88,-91,-87,-79,-66,-48,-28, -7, 16, 37, 56, 71, 83, 89, 90, 86, 76, 62, 45, 24,  2,-20,-41,-59,-74,-84,-90},
    {90, 82, 67, 46, 22, -4,-31,-54,-73,-85,-90,-88,-78,-61,-38,-13, 13, 38, 61, 78, 88, 90, 85, 73, 54, 31,  4,-22,-46,-67,-82,-90,-90,-82,-67,-46,-22,  4, 31, 54, 73, 85, 90, 88, 78, 61, 38, 13,-13,-38,-61,-78,-88,-90,-85,-73,-54,-31, -4, 22, 46, 67, 82, 90},
    {89, 79, 59, 33,  2,-28,-56,-76,-88,-90,-81,-62,-37, -7, 24, 52, 74, 87, 90, 83, 66, 41, 11,-20,-48,-71,-86,-91,-84,-69,-45,-16, 16, 45, 69, 84, 91, 86, 71, 48, 20,-11,-41,-66,-83,-90,-87,-74,-52,-24,  7, 37, 62, 81, 90, 88, 76, 56, 28, -2,-33,-59,-79,-89},
    {89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89, 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89, 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89, 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89},
    {88, 71, 41,  2,-37,-69,-87,-89,-74,-45, -7, 33, 66, 86, 90, 76, 48, 11,-28,-62,-84,-90,-79,-52,-16, 24, 59, 83, 91, 81, 56, 20,-20,-56,-81,-91,-83,-59,-24, 16, 52, 79, 90, 84, 62, 28,-11,-48,-76,-90,-86,-66,-33,  7, 45, 74, 89, 87, 69, 37, -2,-41,-71,-88},
    {88, 67, 31,-13,-54,-82,-90,-78,-46, -4, 38, 73, 90, 85, 61, 22,-22,-61,-85,-90,-73,-38,  4, 46, 78, 90, 82, 54, 13,-31,-67,-88,-88,-67,-31, 13, 54, 82, 90, 78, 46,  4,-38,-73,-90,-85,-61,-22, 22, 61, 85, 90, 73, 38, -4,-46,-78,-90,-82,-54,-13, 31, 67, 88},
    {87, 62, 20,-28,-69,-89,-84,-56,-11, 37, 74, 90, 81, 48,  2,-45,-79,-91,-76,-41,  7, 52, 83, 90, 71, 33,-16,-59,-86,-88,-66,-24, 24, 66, 88, 86, 59, 16,-33,-71,-90,-83,-52, -7, 41, 76, 91, 79, 45, -2,-48,-81,-90,-74,-37, 11, 56, 84, 89, 69, 28,-20,-62,-87},
    {87, 57,  9,-43,-80,-90,-70,-25, 25, 70, 90, 80, 43, -9,-57,-87,-87,-57, -9, 43, 80, 90, 70, 25,-25,-70,-90,-80,-43,  9, 57, 87, 87, 57,  9,-43,-80,-90,-70,-25, 25, 70, 90, 80, 43, -9,-57,-87,-87,-57, -9, 43, 80, 90, 70, 25,-25,-70,-90,-80,-43,  9, 57, 87},
    {86, 52, -2,-56,-87,-84,-48,  7, 59, 88, 83, 45,-11,-62,-89,-81,-41, 16, 66, 90, 79, 37,-20,-69,-90,-76,-33, 24, 71, 91, 74, 28,-28,-74,-91,-71,-24, 33, 76, 90, 69, 20,-37,-79,-90,-66,-16, 41, 81, 89, 62, 11,-45,-83,-88,-59, -7, 48, 84, 87, 56,  2,-52,-86},
    {85, 46,-13,-67,-90,-73,-22, 38, 82, 88, 54, -4,-61,-90,-78,-31, 31, 78, 90, 61,  4,-54,-88,-82,-38, 22, 73, 90, 67, 13,-46,-85,-85,-46, 13, 67, 90, 73, 22,-38,-82,-88,-54,  4, 61, 90, 78, 31,-31,-78,-90,-61, -4, 54, 88, 82, 38,-22,-73,-90,-67,-13, 46, 85},
    {84, 41,-24,-76,-89,-56,  7, 66, 91, 69, 11,-52,-88,-79,-28, 37, 83, 86, 45,-20,-74,-90,-59,  2, 62, 90, 71, 16,-48,-87,-81,-33, 33, 81, 87, 48,-16,-71,-90,-62, -2, 59, 90, 74, 20,-45,-86,-83,-37, 28, 79, 88, 52,-11,-69,-91,-66, -7, 56, 89, 76, 24,-41,-84},
    {83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83},
    {83, 28,-45,-88,-74,-11, 59, 91, 62, -7,-71,-89,-48, 24, 81, 84, 33,-41,-87,-76,-16, 56, 90, 66, -2,-69,-90,-52, 20, 79, 86, 37,-37,-86,-79,-20, 52, 90, 69,  2,-66,-90,-56, 16, 76, 87, 41,-33,-84,-81,-24, 48, 89, 71,  7,-62,-91,-59, 11, 74, 88, 45,-28,-83},
    {82, 22,-54,-90,-61, 13, 78, 85, 31,-46,-90,-67,  4, 73, 88, 38,-38,-88,-73, -4, 67, 90, 46,-31,-85,-78,-13, 61, 90, 54,-22,-82,-82,-22, 54, 90, 61,-13,-78,-85,-31, 46, 90, 67, -4,-73,-88,-38, 38, 88, 73,  4,-67,-90,-46, 31, 85, 78, 13,-61,-90,-54, 22, 82},
    {81, 16,-62,-90,-45, 37, 88, 69, -7,-76,-84,-24, 56, 91, 52,-28,-86,-74, -2, 71, 87, 33,-48,-90,-59, 20, 83, 79, 11,-66,-89,-41, 41, 89, 66,-11,-79,-83,-20, 59, 90, 48,-33,-87,-71,  2, 74, 86, 28,-52,-91,-56, 24, 84, 76,  7,-69,-88,-37, 45, 90, 62,-16,-81},
    {80,  9,-70,-87,-25, 57, 90, 43,-43,-90,-57, 25, 87, 70, -9,-80,-80, -9, 70, 87, 25,-57,-90,-43, 43, 90, 57,-25,-87,-70,  9, 80, 80,  9,-70,-87,-25, 57, 90, 43,-43,-90,-57, 25, 87, 70, -9,-80,-80, -9, 70, 87, 25,-57,-90,-43, 43, 90, 57,-25,-87,-70,  9, 80},
    {79,  2,-76,-81, -7, 74, 83, 11,-71,-84,-16, 69, 86, 20,-66,-87,-24, 62, 88, 28,-59,-89,-33, 56, 90, 37,-52,-90,-41, 48, 91, 45,-45,-91,-48, 41, 90, 52,-37,-90,-56, 33, 89, 59,-28,-88,-62, 24, 87, 66,-20,-86,-69, 16, 84, 71,-11,-83,-74,  7, 81, 76, -2,-79},
    {78, -4,-82,-73, 13, 85, 67,-22,-88,-61, 31, 90, 54,-38,-90,-46, 46, 90, 38,-54,-90,-31, 61, 88, 22,-67,-85,-13, 73, 82,  4,-78,-78,  4, 82, 73,-13,-85,-67, 22, 88, 61,-31,-90,-54, 38, 90, 46,-46,-90,-38, 54, 90, 31,-61,-88,-22, 67, 85, 13,-73,-82, -4, 78},
    {76,-11,-86,-62, 33, 90, 45,-52,-89,-24, 69, 83,  2,-81,-71, 20, 88, 56,-41,-91,-37, 59, 87, 16,-74,-79,  7, 84, 66,-28,-90,-48, 48, 90, 28,-66,-84, -7, 79, 74,-16,-87,-59, 37, 91, 41,-56,-88,-20, 71, 81, -2,-83,-69, 24, 89, 52,-45,-90,-33, 62, 86, 11,-76},
    {75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75, 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75, 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75, 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75},
    {74,-24,-90,-37, 66, 81,-11,-88,-48, 56, 86,  2,-84,-59, 45, 89, 16,-79,-69, 33, 91, 28,-71,-76, 20, 90, 41,-62,-83,  7, 87, 52,-52,-87, -7, 83, 62,-41,-90,-20, 76, 71,-28,-91,-33, 69, 79,-16,-89,-45, 59, 84, -2,-86,-56, 48, 88, 11,-81,-66, 37, 90, 24,-74},
    {73,-31,-90,-22, 78, 67,-38,-90,-13, 82, 61,-46,-88, -4, 85, 54,-54,-85,  4, 88, 46,-61,-82, 13, 90, 38,-67,-78, 22, 90, 31,-73,-73, 31, 90, 22,-78,-67, 38, 90, 13,-82,-61, 46, 88,  4,-85,-54, 54, 85, -4,-88,-46, 61, 82,-13,-90,-38, 67, 78,-22,-90,-31, 73},
    {71,-37,-89, -7, 86, 48,-62,-79, 24, 91, 20,-81,-59, 52, 84,-11,-90,-33, 74, 69,-41,-88, -2, 87, 45,-66,-76, 28, 90, 16,-83,-56, 56, 83,-16,-90,-28, 76, 66,-45,-87,  2, 88, 41,-69,-74, 33, 90, 11,-84,-52, 59, 81,-20,-91,-24, 79, 62,-48,-86,  7, 89, 37,-71},
    {70,-43,-87,  9, 90, 25,-80,-57, 57, 80,-25,-90, -9, 87, 43,-70,-70, 43, 87, -9,-90,-25, 80, 57,-57,-80, 25, 90,  9,-87,-43, 70, 70,-43,-87,  9, 90, 25,-80,-57, 57, 80,-25,-90, -9, 87, 43,-70,-70, 43, 87, -9,-90,-25, 80, 57,-57,-80, 25, 90,  9,-87,-43, 70},
    {69,-48,-83, 24, 90,  2,-89,-28, 81, 52,-66,-71, 45, 84,-20,-90, -7, 88, 33,-79,-56, 62, 74,-41,-86, 16, 91, 11,-87,-37, 76, 59,-59,-76, 37, 87,-11,-91,-16, 86, 41,-74,-62, 56, 79,-33,-88,  7, 90, 20,-84,-45, 71, 66,-52,-81, 28, 89, -2,-90,-24, 83, 48,-69},
    {67,-54,-78, 38, 85,-22,-90,  4, 90, 13,-88,-31, 82, 46,-73,-61, 61, 73,-46,-82, 31, 88,-13,-90, -4, 90, 22,-85,-38, 78, 54,-67,-67, 54, 78,-38,-85, 22, 90, -4,-90,-13, 88, 31,-82,-46, 73, 61,-61,-73, 46, 82,-31,-88, 13, 90,  4,-90,-22, 85, 38,-78,-54, 67},
    {66,-59,-71, 52, 76,-45,-81, 37, 84,-28,-87, 20, 89,-11,-90,  2, 91,  7,-90,-16, 88, 24,-86,-33, 83, 41,-79,-48, 74, 56,-69,-62, 62, 69,-56,-74, 48, 79,-41,-83, 33, 86,-24,-88, 16, 90, -7,-91, -2, 90, 11,-89,-20, 87, 28,-84,-37, 81, 45,-76,-52, 71, 59,-66},
    {64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64},
    {62,-69,-56, 74, 48,-79,-41, 83, 33,-86,-24, 88, 16,-90, -7, 91, -2,-90, 11, 89,-20,-87, 28, 84,-37,-81, 45, 76,-52,-71, 59, 66,-66,-59, 71, 52,-76,-45, 81, 37,-84,-28, 87, 20,-89,-11, 90,  2,-91,  7, 90,-16,-88, 24, 86,-33,-83, 41, 79,-48,-74, 56, 69,-62},
    {61,-73,-46, 82, 31,-88,-13, 90, -4,-90, 22, 85,-38,-78, 54, 67,-67,-54, 78, 38,-85,-22, 90,  4,-90, 13, 88,-31,-82, 46, 73,-61,-61, 73, 46,-82,-31, 88, 13,-90,  4, 90,-22,-85, 38, 78,-54,-67, 67, 54,-78,-38, 85, 22,-90, -4, 90,-13,-88, 31, 82,-46,-73, 61},
    {59,-76,-37, 87, 11,-91, 16, 86,-41,-74, 62, 56,-79,-33, 88,  7,-90, 20, 84,-45,-71, 66, 52,-81,-28, 89,  2,-90, 24, 83,-48,-69, 69, 48,-83,-24, 90, -2,-89, 28, 81,-52,-66, 71, 45,-84,-20, 90, -7,-88, 33, 79,-56,-62, 74, 41,-86,-16, 91,-11,-87, 37, 76,-59},
    {57,-80,-25, 90, -9,-87, 43, 70,-70,-43, 87,  9,-90, 25, 80,-57,-57, 80, 25,-90,  9, 87,-43,-70, 70, 43,-87, -9, 90,-25,-80, 57, 57,-80,-25, 90, -9,-87, 43, 70,-70,-43, 87,  9,-90, 25, 80,-57,-57, 80, 25,-90,  9, 87,-43,-70, 70, 43,-87, -9, 90,-25,-80, 57},
    {56,-83,-16, 90,-28,-76, 66, 45,-87, -2, 88,-41,-69, 74, 33,-90, 11, 84,-52,-59, 81, 20,-91, 24, 79,-62,-48, 86,  7,-89, 37, 71,-71,-37, 89, -7,-86, 48, 62,-79,-24, 91,-20,-81, 59, 52,-84,-11, 90,-33,-74, 69, 41,-88,  2, 87,-45,-66, 76, 28,-90, 16, 83,-56},
    {54,-85, -4, 88,-46,-61, 82, 13,-90, 38, 67,-78,-22, 90,-31,-73, 73, 31,-90, 22, 78,-67,-38, 90,-13,-82, 61, 46,-88,  4, 85,-54,-54, 85,  4,-88, 46, 61,-82,-13, 90,-38,-67, 78, 22,-90, 31, 73,-73,-31, 90,-22,-78, 67, 38,-90, 13, 82,-61,-46, 88, -4,-85, 54},
    {52,-87,  7, 83,-62,-41, 90,-20,-76, 71, 28,-91, 33, 69,-79,-16, 89,-45,-59, 84,  2,-86, 56, 48,-88, 11, 81,-66,-37, 90,-24,-74, 74, 24,-90, 37, 66,-81,-11, 88,-48,-56, 86, -2,-84, 59, 45,-89, 16, 79,-69,-33, 91,-28,-71, 76, 20,-90, 41, 62,-83, -7, 87,-52},
    {50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50, 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50, 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50, 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50},
    {48,-90, 28, 66,-84,  7, 79,-74,-16, 87,-59,-37, 91,-41,-56, 88,-20,-71, 81,  2,-83, 69, 24,-89, 52, 45,-90, 33, 62,-86, 11, 76,-76,-11, 86,-62,-33, 90,-45,-52, 89,-24,-69, 83, -2,-81, 71, 20,-88, 56, 41,-91, 37, 59,-87, 16, 74,-79, -7, 84,-66,-28, 90,-48},
    {46,-90, 38, 54,-90, 31, 61,-88, 22, 67,-85, 13, 73,-82,  4, 78,-78, -4, 82,-73,-13, 85,-67,-22, 88,-61,-31, 90,-54,-38, 90,-46,-46, 90,-38,-54, 90,-31,-61, 88,-22,-67, 85,-13,-73, 82, -4,-78, 78,  4,-82, 73, 13,-85, 67, 22,-88, 61, 31,-90, 54, 38,-90, 46},
    {45,-91, 48, 41,-90, 52, 37,-90, 56, 33,-89, 59, 28,-88, 62, 24,-87, 66, 20,-86, 69, 16,-84, 71, 11,-83, 74,  7,-81, 76,  2,-79, 79, -2,-76, 81, -7,-74, 83,-11,-71, 84,-16,-69, 86,-20,-66, 87,-24,-62, 88,-28,-59, 89,-33,-56, 90,-37,-52, 90,-41,-48, 91,-45},
    {43,-90, 57, 25,-87, 70,  9,-80, 80, -9,-70, 87,-25,-57, 90,-43,-43, 90,-57,-25, 87,-70, -9, 80,-80,  9, 70,-87, 25, 57,-90, 43, 43,-90, 57, 25,-87, 70,  9,-80, 80, -9,-70, 87,-25,-57, 90,-43,-43, 90,-57,-25, 87,-70, -9, 80,-80,  9, 70,-87, 25, 57,-90, 43},
    {41,-89, 66, 11,-79, 83,-20,-59, 90,-48,-33, 87,-71, -2, 74,-86, 28, 52,-91, 56, 24,-84, 76, -7,-69, 88,-37,-45, 90,-62,-16, 81,-81, 16, 62,-90, 45, 37,-88, 69,  7,-76, 84,-24,-56, 91,-52,-28, 86,-74,  2, 71,-87, 33, 48,-90, 59, 20,-83, 79,-11,-66, 89,-41},
    {38,-88, 73, -4,-67, 90,-46,-31, 85,-78, 13, 61,-90, 54, 22,-82, 82,-22,-54, 90,-61,-13, 78,-85, 31, 46,-90, 67,  4,-73, 88,-38,-38, 88,-73,  4, 67,-90, 46, 31,-85, 78,-13,-61, 90,-54,-22, 82,-82, 22, 54,-90, 61, 13,-78, 85,-31,-46, 90,-67, -4, 73,-88, 38},
    {37,-86, 79,-20,-52, 90,-69,  2, 66,-90, 56, 16,-76, 87,-41,-33, 84,-81, 24, 48,-89, 71, -7,-62, 91,-59,-11, 74,-88, 45, 28,-83, 83,-28,-45, 88,-74, 11, 59,-91, 62,  7,-71, 89,-48,-24, 81,-84, 33, 41,-87, 76,-16,-56, 90,-66, -2, 69,-90, 52, 20,-79, 86,-37},
    {36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36},
    {33,-81, 87,-48,-16, 71,-90, 62, -2,-59, 90,-74, 20, 45,-86, 83,-37,-28, 79,-88, 52, 11,-69, 91,-66,  7, 56,-89, 76,-24,-41, 84,-84, 41, 24,-76, 89,-56, -7, 66,-91, 69,-11,-52, 88,-79, 28, 37,-83, 86,-45,-20, 74,-90, 59,  2,-62, 90,-71, 16, 48,-87, 81,-33},
    {31,-78, 90,-61,  4, 54,-88, 82,-38,-22, 73,-90, 67,-13,-46, 85,-85, 46, 13,-67, 90,-73, 22, 38,-82, 88,-54, -4, 61,-90, 78,-31,-31, 78,-90, 61, -4,-54, 88,-82, 38, 22,-73, 90,-67, 13, 46,-85, 85,-46,-13, 67,-90, 73,-22,-38, 82,-88, 54,  4,-61, 90,-78, 31},
    {28,-74, 91,-71, 24, 33,-76, 90,-69, 20, 37,-79, 90,-66, 16, 41,-81, 89,-62, 11, 45,-83, 88,-59,  7, 48,-84, 87,-56,  2, 52,-86, 86,-52, -2, 56,-87, 84,-48, -7, 59,-88, 83,-45,-11, 62,-89, 81,-41,-16, 66,-90, 79,-37,-20, 69,-90, 76,-33,-24, 71,-91, 74,-28},
    {25,-70, 90,-80, 43,  9,-57, 87,-87, 57, -9,-43, 80,-90, 70,-25,-25, 70,-90, 80,-43, -9, 57,-87, 87,-57,  9, 43,-80, 90,-70, 25, 25,-70, 90,-80, 43,  9,-57, 87,-87, 57, -9,-43, 80,-90, 70,-25,-25, 70,-90, 80,-43, -9, 57,-87, 87,-57,  9, 43,-80, 90,-70, 25},
    {24,-66, 88,-86, 59,-16,-33, 71,-90, 83,-52,  7, 41,-76, 91,-79, 45,  2,-48, 81,-90, 74,-37,-11, 56,-84, 89,-69, 28, 20,-62, 87,-87, 62,-20,-28, 69,-89, 84,-56, 11, 37,-74, 90,-81, 48, -2,-45, 79,-91, 76,-41, -7, 52,-83, 90,-71, 33, 16,-59, 86,-88, 66,-24},
    {22,-61, 85,-90, 73,-38, -4, 46,-78, 90,-82, 54,-13,-31, 67,-88, 88,-67, 31, 13,-54, 82,-90, 78,-46,  4, 38,-73, 90,-85, 61,-22,-22, 61,-85, 90,-73, 38,  4,-46, 78,-90, 82,-54, 13, 31,-67, 88,-88, 67,-31,-13, 54,-82, 90,-78, 46, -4,-38, 73,-90, 85,-61, 22},
    {20,-56, 81,-91, 83,-59, 24, 16,-52, 79,-90, 84,-62, 28, 11,-48, 76,-90, 86,-66, 33,  7,-45, 74,-89, 87,-69, 37,  2,-41, 71,-88, 88,-71, 41, -2,-37, 69,-87, 89,-74, 45, -7,-33, 66,-86, 90,-76, 48,-11,-28, 62,-84, 90,-79, 52,-16,-24, 59,-83, 91,-81, 56,-20},
    {18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18, 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18, 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18, 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18},
    {16,-45, 69,-84, 91,-86, 71,-48, 20, 11,-41, 66,-83, 90,-87, 74,-52, 24,  7,-37, 62,-81, 90,-88, 76,-56, 28,  2,-33, 59,-79, 89,-89, 79,-59, 33, -2,-28, 56,-76, 88,-90, 81,-62, 37, -7,-24, 52,-74, 87,-90, 83,-66, 41,-11,-20, 48,-71, 86,-91, 84,-69, 45,-16},
    {13,-38, 61,-78, 88,-90, 85,-73, 54,-31,  4, 22,-46, 67,-82, 90,-90, 82,-67, 46,-22, -4, 31,-54, 73,-85, 90,-88, 78,-61, 38,-13,-13, 38,-61, 78,-88, 90,-85, 73,-54, 31, -4,-22, 46,-67, 82,-90, 90,-82, 67,-46, 22,  4,-31, 54,-73, 85,-90, 88,-78, 61,-38, 13},
    {11,-33, 52,-69, 81,-88, 91,-87, 79,-66, 48,-28,  7, 16,-37, 56,-71, 83,-89, 90,-86, 76,-62, 45,-24,  2, 20,-41, 59,-74, 84,-90, 90,-84, 74,-59, 41,-20, -2, 24,-45, 62,-76, 86,-90, 89,-83, 71,-56, 37,-16, -7, 28,-48, 66,-79, 87,-91, 88,-81, 69,-52, 33,-11},
    { 9,-25, 43,-57, 70,-80, 87,-90, 90,-87, 80,-70, 57,-43, 25, -9, -9, 25,-43, 57,-70, 80,-87, 90,-90, 87,-80, 70,-57, 43,-25,  9,  9,-25, 43,-57, 70,-80, 87,-90, 90,-87, 80,-70, 57,-43, 25, -9, -9, 25,-43, 57,-70, 80,-87, 90,-90, 87,-80, 70,-57, 43,-25,  9},
    { 7,-20, 33,-45, 56,-66, 74,-81, 86,-89, 91,-90, 87,-83, 76,-69, 59,-48, 37,-24, 11,  2,-16, 28,-41, 52,-62, 71,-79, 84,-88, 90,-90, 88,-84, 79,-71, 62,-52, 41,-28, 16, -2,-11, 24,-37, 48,-59, 69,-76, 83,-87, 90,-91, 89,-86, 81,-74, 66,-56, 45,-33, 20, -7},
    { 4,-13, 22,-31, 38,-46, 54,-61, 67,-73, 78,-82, 85,-88, 90,-90, 90,-90, 88,-85, 82,-78, 73,-67, 61,-54, 46,-38, 31,-22, 13, -4, -4, 13,-22, 31,-38, 46,-54, 61,-67, 73,-78, 82,-85, 88,-90, 90,-90, 90,-88, 85,-82, 78,-73, 67,-61, 54,-46, 38,-31, 22,-13,  4},
    { 2, -7, 11,-16, 20,-24, 28,-33, 37,-41, 45,-48, 52,-56, 59,-62, 66,-69, 71,-74, 76,-79, 81,-83, 84,-86, 87,-88, 89,-90, 90,-91, 91,-90, 90,-89, 88,-87, 86,-84, 83,-81, 79,-76, 74,-71, 69,-66, 62,-59, 56,-52, 48,-45, 41,-37, 33,-28, 24,-20, 16,-11,  7, -2},
#else
    {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,},
    {90, 90, 90, 89, 88, 87, 86, 84, 83, 81, 79, 76, 74, 71, 69, 66, 62, 59, 56, 52, 48, 45, 41, 37, 33, 28, 24, 20, 15, 11,  7,  2, -2, -7,-11,-15,-20,-24,-28,-33,-37,-41,-45,-48,-52,-56,-59,-62,-66,-69,-71,-74,-76,-79,-81,-83,-84,-86,-87,-88,-89,-90,-90,-90,},
    {90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13,  4, -4,-13,-22,-31,-38,-46,-54,-61,-67,-73,-78,-82,-85,-88,-90,-90,-90,-90,-88,-85,-82,-78,-73,-67,-61,-54,-46,-38,-31,-22,-13, -4,  4, 13, 22, 31, 38, 46, 54, 61, 67, 73, 78, 82, 85, 88, 90, 90,},
    {90, 88, 84, 79, 71, 62, 52, 41, 28, 15,  2,-11,-24,-37,-48,-59,-69,-76,-83,-87,-90,-90,-89,-86,-81,-74,-66,-56,-45,-33,-20, -7,  7, 20, 33, 45, 56, 66, 74, 81, 86, 89, 90, 90, 87, 83, 76, 69, 59, 48, 37, 24, 11, -2,-15,-28,-41,-52,-62,-71,-79,-84,-88,-90,},
    {90, 87, 80, 70, 57, 43, 25,  9, -9,-25,-43,-57,-70,-80,-87,-90,-90,-87,-80,-70,-57,-43,-25, -9,  9, 25, 43, 57, 70, 80, 87, 90, 90, 87, 80, 70, 57, 43, 25,  9, -9,-25,-43,-57,-70,-80,-87,-90,-90,-87,-80,-70,-57,-43,-25, -9,  9, 25, 43, 57, 70, 80, 87, 90,},
    {90, 84, 74, 59, 41, 20, -2,-24,-45,-62,-76,-86,-90,-89,-83,-71,-56,-37,-15,  7, 28, 48, 66, 79, 87, 90, 88, 81, 69, 52, 33, 11,-11,-33,-52,-69,-81,-88,-90,-87,-79,-66,-48,-28, -7, 15, 37, 56, 71, 83, 89, 90, 86, 76, 62, 45, 24,  2,-20,-41,-59,-74,-84,-90,},
    {90, 82, 67, 46, 22, -4,-31,-54,-73,-85,-90,-88,-78,-61,-38,-13, 13, 38, 61, 78, 88, 90, 85, 73, 54, 31,  4,-22,-46,-67,-82,-90,-90,-82,-67,-46,-22,  4, 31, 54, 73, 85, 90, 88, 78, 61, 38, 13,-13,-38,-61,-78,-88,-90,-85,-73,-54,-31, -4, 22, 46, 67, 82, 90,},
    {89, 79, 59, 33,  2,-28,-56,-76,-88,-90,-81,-62,-37, -7, 24, 52, 74, 87, 90, 83, 66, 41, 11,-20,-48,-71,-86,-90,-84,-69,-45,-15, 15, 45, 69, 84, 90, 86, 71, 48, 20,-11,-41,-66,-83,-90,-87,-74,-52,-24,  7, 37, 62, 81, 90, 88, 76, 56, 28, -2,-33,-59,-79,-89,},
    {89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89, 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89, 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89, 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89,},
    {88, 71, 41,  2,-37,-69,-87,-89,-74,-45, -7, 33, 66, 86, 90, 76, 48, 11,-28,-62,-84,-90,-79,-52,-15, 24, 59, 83, 90, 81, 56, 20,-20,-56,-81,-90,-83,-59,-24, 15, 52, 79, 90, 84, 62, 28,-11,-48,-76,-90,-86,-66,-33,  7, 45, 74, 89, 87, 69, 37, -2,-41,-71,-88,},
    {88, 67, 31,-13,-54,-82,-90,-78,-46, -4, 38, 73, 90, 85, 61, 22,-22,-61,-85,-90,-73,-38,  4, 46, 78, 90, 82, 54, 13,-31,-67,-88,-88,-67,-31, 13, 54, 82, 90, 78, 46,  4,-38,-73,-90,-85,-61,-22, 22, 61, 85, 90, 73, 38, -4,-46,-78,-90,-82,-54,-13, 31, 67, 88,},
    {87, 62, 20,-28,-69,-89,-84,-56,-11, 37, 74, 90, 81, 48,  2,-45,-79,-90,-76,-41,  7, 52, 83, 90, 71, 33,-15,-59,-86,-88,-66,-24, 24, 66, 88, 86, 59, 15,-33,-71,-90,-83,-52, -7, 41, 76, 90, 79, 45, -2,-48,-81,-90,-74,-37, 11, 56, 84, 89, 69, 28,-20,-62,-87,},
    {87, 57,  9,-43,-80,-90,-70,-25, 25, 70, 90, 80, 43, -9,-57,-87,-87,-57, -9, 43, 80, 90, 70, 25,-25,-70,-90,-80,-43,  9, 57, 87, 87, 57,  9,-43,-80,-90,-70,-25, 25, 70, 90, 80, 43, -9,-57,-87,-87,-57, -9, 43, 80, 90, 70, 25,-25,-70,-90,-80,-43,  9, 57, 87,},
    {86, 52, -2,-56,-87,-84,-48,  7, 59, 88, 83, 45,-11,-62,-89,-81,-41, 15, 66, 90, 79, 37,-20,-69,-90,-76,-33, 24, 71, 90, 74, 28,-28,-74,-90,-71,-24, 33, 76, 90, 69, 20,-37,-79,-90,-66,-15, 41, 81, 89, 62, 11,-45,-83,-88,-59, -7, 48, 84, 87, 56,  2,-52,-86,},
    {85, 46,-13,-67,-90,-73,-22, 38, 82, 88, 54, -4,-61,-90,-78,-31, 31, 78, 90, 61,  4,-54,-88,-82,-38, 22, 73, 90, 67, 13,-46,-85,-85,-46, 13, 67, 90, 73, 22,-38,-82,-88,-54,  4, 61, 90, 78, 31,-31,-78,-90,-61, -4, 54, 88, 82, 38,-22,-73,-90,-67,-13, 46, 85,},
    {84, 41,-24,-76,-89,-56,  7, 66, 90, 69, 11,-52,-88,-79,-28, 37, 83, 86, 45,-20,-74,-90,-59,  2, 62, 90, 71, 15,-48,-87,-81,-33, 33, 81, 87, 48,-15,-71,-90,-62, -2, 59, 90, 74, 20,-45,-86,-83,-37, 28, 79, 88, 52,-11,-69,-90,-66, -7, 56, 89, 76, 24,-41,-84,},
    {83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83,},
    {83, 28,-45,-88,-74,-11, 59, 90, 62, -7,-71,-89,-48, 24, 81, 84, 33,-41,-87,-76,-15, 56, 90, 66, -2,-69,-90,-52, 20, 79, 86, 37,-37,-86,-79,-20, 52, 90, 69,  2,-66,-90,-56, 15, 76, 87, 41,-33,-84,-81,-24, 48, 89, 71,  7,-62,-90,-59, 11, 74, 88, 45,-28,-83,},
    {82, 22,-54,-90,-61, 13, 78, 85, 31,-46,-90,-67,  4, 73, 88, 38,-38,-88,-73, -4, 67, 90, 46,-31,-85,-78,-13, 61, 90, 54,-22,-82,-82,-22, 54, 90, 61,-13,-78,-85,-31, 46, 90, 67, -4,-73,-88,-38, 38, 88, 73,  4,-67,-90,-46, 31, 85, 78, 13,-61,-90,-54, 22, 82,},
    {81, 15,-62,-90,-45, 37, 88, 69, -7,-76,-84,-24, 56, 90, 52,-28,-86,-74, -2, 71, 87, 33,-48,-90,-59, 20, 83, 79, 11,-66,-89,-41, 41, 89, 66,-11,-79,-83,-20, 59, 90, 48,-33,-87,-71,  2, 74, 86, 28,-52,-90,-56, 24, 84, 76,  7,-69,-88,-37, 45, 90, 62,-15,-81,},
    {80,  9,-70,-87,-25, 57, 90, 43,-43,-90,-57, 25, 87, 70, -9,-80,-80, -9, 70, 87, 25,-57,-90,-43, 43, 90, 57,-25,-87,-70,  9, 80, 80,  9,-70,-87,-25, 57, 90, 43,-43,-90,-57, 25, 87, 70, -9,-80,-80, -9, 70, 87, 25,-57,-90,-43, 43, 90, 57,-25,-87,-70,  9, 80,},
    {79,  2,-76,-81, -7, 74, 83, 11,-71,-84,-15, 69, 86, 20,-66,-87,-24, 62, 88, 28,-59,-89,-33, 56, 90, 37,-52,-90,-41, 48, 90, 45,-45,-90,-48, 41, 90, 52,-37,-90,-56, 33, 89, 59,-28,-88,-62, 24, 87, 66,-20,-86,-69, 15, 84, 71,-11,-83,-74,  7, 81, 76, -2,-79,},
    {78, -4,-82,-73, 13, 85, 67,-22,-88,-61, 31, 90, 54,-38,-90,-46, 46, 90, 38,-54,-90,-31, 61, 88, 22,-67,-85,-13, 73, 82,  4,-78,-78,  4, 82, 73,-13,-85,-67, 22, 88, 61,-31,-90,-54, 38, 90, 46,-46,-90,-38, 54, 90, 31,-61,-88,-22, 67, 85, 13,-73,-82, -4, 78,},
    {76,-11,-86,-62, 33, 90, 45,-52,-89,-24, 69, 83,  2,-81,-71, 20, 88, 56,-41,-90,-37, 59, 87, 15,-74,-79,  7, 84, 66,-28,-90,-48, 48, 90, 28,-66,-84, -7, 79, 74,-15,-87,-59, 37, 90, 41,-56,-88,-20, 71, 81, -2,-83,-69, 24, 89, 52,-45,-90,-33, 62, 86, 11,-76,},
    {75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75, 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75, 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75, 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75,},
    {74,-24,-90,-37, 66, 81,-11,-88,-48, 56, 86,  2,-84,-59, 45, 89, 15,-79,-69, 33, 90, 28,-71,-76, 20, 90, 41,-62,-83,  7, 87, 52,-52,-87, -7, 83, 62,-41,-90,-20, 76, 71,-28,-90,-33, 69, 79,-15,-89,-45, 59, 84, -2,-86,-56, 48, 88, 11,-81,-66, 37, 90, 24,-74,},
    {73,-31,-90,-22, 78, 67,-38,-90,-13, 82, 61,-46,-88, -4, 85, 54,-54,-85,  4, 88, 46,-61,-82, 13, 90, 38,-67,-78, 22, 90, 31,-73,-73, 31, 90, 22,-78,-67, 38, 90, 13,-82,-61, 46, 88,  4,-85,-54, 54, 85, -4,-88,-46, 61, 82,-13,-90,-38, 67, 78,-22,-90,-31, 73,},
    {71,-37,-89, -7, 86, 48,-62,-79, 24, 90, 20,-81,-59, 52, 84,-11,-90,-33, 74, 69,-41,-88, -2, 87, 45,-66,-76, 28, 90, 15,-83,-56, 56, 83,-15,-90,-28, 76, 66,-45,-87,  2, 88, 41,-69,-74, 33, 90, 11,-84,-52, 59, 81,-20,-90,-24, 79, 62,-48,-86,  7, 89, 37,-71,},
    {70,-43,-87,  9, 90, 25,-80,-57, 57, 80,-25,-90, -9, 87, 43,-70,-70, 43, 87, -9,-90,-25, 80, 57,-57,-80, 25, 90,  9,-87,-43, 70, 70,-43,-87,  9, 90, 25,-80,-57, 57, 80,-25,-90, -9, 87, 43,-70,-70, 43, 87, -9,-90,-25, 80, 57,-57,-80, 25, 90,  9,-87,-43, 70,},
    {69,-48,-83, 24, 90,  2,-89,-28, 81, 52,-66,-71, 45, 84,-20,-90, -7, 88, 33,-79,-56, 62, 74,-41,-86, 15, 90, 11,-87,-37, 76, 59,-59,-76, 37, 87,-11,-90,-15, 86, 41,-74,-62, 56, 79,-33,-88,  7, 90, 20,-84,-45, 71, 66,-52,-81, 28, 89, -2,-90,-24, 83, 48,-69,},
    {67,-54,-78, 38, 85,-22,-90,  4, 90, 13,-88,-31, 82, 46,-73,-61, 61, 73,-46,-82, 31, 88,-13,-90, -4, 90, 22,-85,-38, 78, 54,-67,-67, 54, 78,-38,-85, 22, 90, -4,-90,-13, 88, 31,-82,-46, 73, 61,-61,-73, 46, 82,-31,-88, 13, 90,  4,-90,-22, 85, 38,-78,-54, 67,},
    {66,-59,-71, 52, 76,-45,-81, 37, 84,-28,-87, 20, 89,-11,-90,  2, 90,  7,-90,-15, 88, 24,-86,-33, 83, 41,-79,-48, 74, 56,-69,-62, 62, 69,-56,-74, 48, 79,-41,-83, 33, 86,-24,-88, 15, 90, -7,-90, -2, 90, 11,-89,-20, 87, 28,-84,-37, 81, 45,-76,-52, 71, 59,-66,},
    {64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64,},
    {62,-69,-56, 74, 48,-79,-41, 83, 33,-86,-24, 88, 15,-90, -7, 90, -2,-90, 11, 89,-20,-87, 28, 84,-37,-81, 45, 76,-52,-71, 59, 66,-66,-59, 71, 52,-76,-45, 81, 37,-84,-28, 87, 20,-89,-11, 90,  2,-90,  7, 90,-15,-88, 24, 86,-33,-83, 41, 79,-48,-74, 56, 69,-62,},
    {61,-73,-46, 82, 31,-88,-13, 90, -4,-90, 22, 85,-38,-78, 54, 67,-67,-54, 78, 38,-85,-22, 90,  4,-90, 13, 88,-31,-82, 46, 73,-61,-61, 73, 46,-82,-31, 88, 13,-90,  4, 90,-22,-85, 38, 78,-54,-67, 67, 54,-78,-38, 85, 22,-90, -4, 90,-13,-88, 31, 82,-46,-73, 61,},
    {59,-76,-37, 87, 11,-90, 15, 86,-41,-74, 62, 56,-79,-33, 88,  7,-90, 20, 84,-45,-71, 66, 52,-81,-28, 89,  2,-90, 24, 83,-48,-69, 69, 48,-83,-24, 90, -2,-89, 28, 81,-52,-66, 71, 45,-84,-20, 90, -7,-88, 33, 79,-56,-62, 74, 41,-86,-15, 90,-11,-87, 37, 76,-59,},
    {57,-80,-25, 90, -9,-87, 43, 70,-70,-43, 87,  9,-90, 25, 80,-57,-57, 80, 25,-90,  9, 87,-43,-70, 70, 43,-87, -9, 90,-25,-80, 57, 57,-80,-25, 90, -9,-87, 43, 70,-70,-43, 87,  9,-90, 25, 80,-57,-57, 80, 25,-90,  9, 87,-43,-70, 70, 43,-87, -9, 90,-25,-80, 57,},
    {56,-83,-15, 90,-28,-76, 66, 45,-87, -2, 88,-41,-69, 74, 33,-90, 11, 84,-52,-59, 81, 20,-90, 24, 79,-62,-48, 86,  7,-89, 37, 71,-71,-37, 89, -7,-86, 48, 62,-79,-24, 90,-20,-81, 59, 52,-84,-11, 90,-33,-74, 69, 41,-88,  2, 87,-45,-66, 76, 28,-90, 15, 83,-56,},
    {54,-85, -4, 88,-46,-61, 82, 13,-90, 38, 67,-78,-22, 90,-31,-73, 73, 31,-90, 22, 78,-67,-38, 90,-13,-82, 61, 46,-88,  4, 85,-54,-54, 85,  4,-88, 46, 61,-82,-13, 90,-38,-67, 78, 22,-90, 31, 73,-73,-31, 90,-22,-78, 67, 38,-90, 13, 82,-61,-46, 88, -4,-85, 54,},
    {52,-87,  7, 83,-62,-41, 90,-20,-76, 71, 28,-90, 33, 69,-79,-15, 89,-45,-59, 84,  2,-86, 56, 48,-88, 11, 81,-66,-37, 90,-24,-74, 74, 24,-90, 37, 66,-81,-11, 88,-48,-56, 86, -2,-84, 59, 45,-89, 15, 79,-69,-33, 90,-28,-71, 76, 20,-90, 41, 62,-83, -7, 87,-52,},
    {50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50, 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50, 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50, 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50,},
    {48,-90, 28, 66,-84,  7, 79,-74,-15, 87,-59,-37, 90,-41,-56, 88,-20,-71, 81,  2,-83, 69, 24,-89, 52, 45,-90, 33, 62,-86, 11, 76,-76,-11, 86,-62,-33, 90,-45,-52, 89,-24,-69, 83, -2,-81, 71, 20,-88, 56, 41,-90, 37, 59,-87, 15, 74,-79, -7, 84,-66,-28, 90,-48,},
    {46,-90, 38, 54,-90, 31, 61,-88, 22, 67,-85, 13, 73,-82,  4, 78,-78, -4, 82,-73,-13, 85,-67,-22, 88,-61,-31, 90,-54,-38, 90,-46,-46, 90,-38,-54, 90,-31,-61, 88,-22,-67, 85,-13,-73, 82, -4,-78, 78,  4,-82, 73, 13,-85, 67, 22,-88, 61, 31,-90, 54, 38,-90, 46,},
    {45,-90, 48, 41,-90, 52, 37,-90, 56, 33,-89, 59, 28,-88, 62, 24,-87, 66, 20,-86, 69, 15,-84, 71, 11,-83, 74,  7,-81, 76,  2,-79, 79, -2,-76, 81, -7,-74, 83,-11,-71, 84,-15,-69, 86,-20,-66, 87,-24,-62, 88,-28,-59, 89,-33,-56, 90,-37,-52, 90,-41,-48, 90,-45,},
    {43,-90, 57, 25,-87, 70,  9,-80, 80, -9,-70, 87,-25,-57, 90,-43,-43, 90,-57,-25, 87,-70, -9, 80,-80,  9, 70,-87, 25, 57,-90, 43, 43,-90, 57, 25,-87, 70,  9,-80, 80, -9,-70, 87,-25,-57, 90,-43,-43, 90,-57,-25, 87,-70, -9, 80,-80,  9, 70,-87, 25, 57,-90, 43,},
    {41,-89, 66, 11,-79, 83,-20,-59, 90,-48,-33, 87,-71, -2, 74,-86, 28, 52,-90, 56, 24,-84, 76, -7,-69, 88,-37,-45, 90,-62,-15, 81,-81, 15, 62,-90, 45, 37,-88, 69,  7,-76, 84,-24,-56, 90,-52,-28, 86,-74,  2, 71,-87, 33, 48,-90, 59, 20,-83, 79,-11,-66, 89,-41,},
    {38,-88, 73, -4,-67, 90,-46,-31, 85,-78, 13, 61,-90, 54, 22,-82, 82,-22,-54, 90,-61,-13, 78,-85, 31, 46,-90, 67,  4,-73, 88,-38,-38, 88,-73,  4, 67,-90, 46, 31,-85, 78,-13,-61, 90,-54,-22, 82,-82, 22, 54,-90, 61, 13,-78, 85,-31,-46, 90,-67, -4, 73,-88, 38,},
    {37,-86, 79,-20,-52, 90,-69,  2, 66,-90, 56, 15,-76, 87,-41,-33, 84,-81, 24, 48,-89, 71, -7,-62, 90,-59,-11, 74,-88, 45, 28,-83, 83,-28,-45, 88,-74, 11, 59,-90, 62,  7,-71, 89,-48,-24, 81,-84, 33, 41,-87, 76,-15,-56, 90,-66, -2, 69,-90, 52, 20,-79, 86,-37,},
    {36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36,},
    {33,-81, 87,-48,-15, 71,-90, 62, -2,-59, 90,-74, 20, 45,-86, 83,-37,-28, 79,-88, 52, 11,-69, 90,-66,  7, 56,-89, 76,-24,-41, 84,-84, 41, 24,-76, 89,-56, -7, 66,-90, 69,-11,-52, 88,-79, 28, 37,-83, 86,-45,-20, 74,-90, 59,  2,-62, 90,-71, 15, 48,-87, 81,-33,},
    {31,-78, 90,-61,  4, 54,-88, 82,-38,-22, 73,-90, 67,-13,-46, 85,-85, 46, 13,-67, 90,-73, 22, 38,-82, 88,-54, -4, 61,-90, 78,-31,-31, 78,-90, 61, -4,-54, 88,-82, 38, 22,-73, 90,-67, 13, 46,-85, 85,-46,-13, 67,-90, 73,-22,-38, 82,-88, 54,  4,-61, 90,-78, 31,},
    {28,-74, 90,-71, 24, 33,-76, 90,-69, 20, 37,-79, 90,-66, 15, 41,-81, 89,-62, 11, 45,-83, 88,-59,  7, 48,-84, 87,-56,  2, 52,-86, 86,-52, -2, 56,-87, 84,-48, -7, 59,-88, 83,-45,-11, 62,-89, 81,-41,-15, 66,-90, 79,-37,-20, 69,-90, 76,-33,-24, 71,-90, 74,-28,},
    {25,-70, 90,-80, 43,  9,-57, 87,-87, 57, -9,-43, 80,-90, 70,-25,-25, 70,-90, 80,-43, -9, 57,-87, 87,-57,  9, 43,-80, 90,-70, 25, 25,-70, 90,-80, 43,  9,-57, 87,-87, 57, -9,-43, 80,-90, 70,-25,-25, 70,-90, 80,-43, -9, 57,-87, 87,-57,  9, 43,-80, 90,-70, 25,},
    {24,-66, 88,-86, 59,-15,-33, 71,-90, 83,-52,  7, 41,-76, 90,-79, 45,  2,-48, 81,-90, 74,-37,-11, 56,-84, 89,-69, 28, 20,-62, 87,-87, 62,-20,-28, 69,-89, 84,-56, 11, 37,-74, 90,-81, 48, -2,-45, 79,-90, 76,-41, -7, 52,-83, 90,-71, 33, 15,-59, 86,-88, 66,-24,},
    {22,-61, 85,-90, 73,-38, -4, 46,-78, 90,-82, 54,-13,-31, 67,-88, 88,-67, 31, 13,-54, 82,-90, 78,-46,  4, 38,-73, 90,-85, 61,-22,-22, 61,-85, 90,-73, 38,  4,-46, 78,-90, 82,-54, 13, 31,-67, 88,-88, 67,-31,-13, 54,-82, 90,-78, 46, -4,-38, 73,-90, 85,-61, 22,},
    {20,-56, 81,-90, 83,-59, 24, 15,-52, 79,-90, 84,-62, 28, 11,-48, 76,-90, 86,-66, 33,  7,-45, 74,-89, 87,-69, 37,  2,-41, 71,-88, 88,-71, 41, -2,-37, 69,-87, 89,-74, 45, -7,-33, 66,-86, 90,-76, 48,-11,-28, 62,-84, 90,-79, 52,-15,-24, 59,-83, 90,-81, 56,-20,},
    {18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18, 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18, 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18, 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18,},
    {15,-45, 69,-84, 90,-86, 71,-48, 20, 11,-41, 66,-83, 90,-87, 74,-52, 24,  7,-37, 62,-81, 90,-88, 76,-56, 28,  2,-33, 59,-79, 89,-89, 79,-59, 33, -2,-28, 56,-76, 88,-90, 81,-62, 37, -7,-24, 52,-74, 87,-90, 83,-66, 41,-11,-20, 48,-71, 86,-90, 84,-69, 45,-15,},
    {13,-38, 61,-78, 88,-90, 85,-73, 54,-31,  4, 22,-46, 67,-82, 90,-90, 82,-67, 46,-22, -4, 31,-54, 73,-85, 90,-88, 78,-61, 38,-13,-13, 38,-61, 78,-88, 90,-85, 73,-54, 31, -4,-22, 46,-67, 82,-90, 90,-82, 67,-46, 22,  4,-31, 54,-73, 85,-90, 88,-78, 61,-38, 13,},
    {11,-33, 52,-69, 81,-88, 90,-87, 79,-66, 48,-28,  7, 15,-37, 56,-71, 83,-89, 90,-86, 76,-62, 45,-24,  2, 20,-41, 59,-74, 84,-90, 90,-84, 74,-59, 41,-20, -2, 24,-45, 62,-76, 86,-90, 89,-83, 71,-56, 37,-15, -7, 28,-48, 66,-79, 87,-90, 88,-81, 69,-52, 33,-11,},
    {9,-25, 43,-57, 70,-80, 87,-90, 90,-87, 80,-70, 57,-43, 25, -9, -9, 25,-43, 57,-70, 80,-87, 90,-90, 87,-80, 70,-57, 43,-25,  9,  9,-25, 43,-57, 70,-80, 87,-90, 90,-87, 80,-70, 57,-43, 25, -9, -9, 25,-43, 57,-70, 80,-87, 90,-90, 87,-80, 70,-57, 43,-25,  9, },
    {7,-20, 33,-45, 56,-66, 74,-81, 86,-89, 90,-90, 87,-83, 76,-69, 59,-48, 37,-24, 11,  2,-15, 28,-41, 52,-62, 71,-79, 84,-88, 90,-90, 88,-84, 79,-71, 62,-52, 41,-28, 15, -2,-11, 24,-37, 48,-59, 69,-76, 83,-87, 90,-90, 89,-86, 81,-74, 66,-56, 45,-33, 20, -7, },
    {4,-13, 22,-31, 38,-46, 54,-61, 67,-73, 78,-82, 85,-88, 90,-90, 90,-90, 88,-85, 82,-78, 73,-67, 61,-54, 46,-38, 31,-22, 13, -4, -4, 13,-22, 31,-38, 46,-54, 61,-67, 73,-78, 82,-85, 88,-90, 90,-90, 90,-88, 85,-82, 78,-73, 67,-61, 54,-46, 38,-31, 22,-13,  4, },
    {2, -7, 11,-15, 20,-24, 28,-33, 37,-41, 45,-48, 52,-56, 59,-62, 66,-69, 71,-74, 76,-79, 81,-83, 84,-86, 87,-88, 89,-90, 90,-90, 90,-90, 90,-89, 88,-87, 86,-84, 83,-81, 79,-76, 74,-71, 69,-66, 62,-59, 56,-52, 48,-45, 41,-37, 33,-28, 24,-20, 15,-11,  7, -2, }
#endif
};

static const int16_t *transform_table[5] = { &g1mat_hevc[0][0], &g2mat_hevc[0][0], &g3mat_hevc[0][0], &g4mat_hevc[0][0], &g5mat_hevc[0][0]};

void transform (const int16_t *block, int16_t *coeff, int size, int fast, int bitdepth)
{
  if (use_simd)
    transform_simd(block, coeff, size, fast, bitdepth);
  else {
    int16_t tmp[MAX_TR_SIZE][MAX_TR_SIZE];
    int16_t tmp2[32*32];
    const int16_t * tr_matrix;
    const int16_t *in = block;
    int tr_log2size = log2i(size);
    int qsize = min(size, MAX_QUANT_SIZE);
    int shift_1, shift_2, add_1, add_2;
    int16_t i, j, m, n, sum, size1, scale;

    size1 = size;
    scale = 1;
    if (size > (32>>fast)) {
      /* Simplification of larger transforms */
      size1 = 32 >> fast;
      scale = size / size1;
      for (i = 0; i < size1; i++) {
        for (j = 0; j < size1; j++) {
          sum = 0;
          for (m = 0; m < scale; m++) {
            for (n = 0; n < scale; n++) {
              // Saturate to match SIMD implementation
              sum = min(max(sum + block[(i * scale + m) * size + j * scale + n], -16384), 16383);
            }
          }
          tmp2[i * size1 + j] = sum;
        }
      }
      in = tmp2;
    }

    /* Set up core transform parameters */
    tr_log2size = log2i(size1);
    tr_matrix = transform_table[tr_log2size - 2];
    shift_1 = log2i(size) + log2i(scale) + bitdepth - 8; //averaging of scale*scale pixels in simplified transform implies increase of shift_1 by log2i(scale) bits
    add_1 = 1 << (shift_1 - 1);
    shift_2 = tr_log2size + 5;
    add_2 = 1 << (shift_2 - 1);

    /* 1st dimension */
    for (int i = 0; i < qsize; i++){
      for (int j = 0; j < size1; j++){
        int sum = 0;
        for (int k = 0; k < size1; k++){
          sum += tr_matrix[i*size1 + k] * in[j*size1 + k];
        }
        tmp[i][j] = (sum + add_1) >> shift_1;
      }
    }
    /* 2nd dimension */
    for (int i = 0; i < qsize; i++){
      for (int j = 0; j < qsize; j++){
        int sum = 0;
        for (int k = 0; k < size1; k++){
          sum += tr_matrix[i*size1 + k] * tmp[j][k];
        }
        coeff[i*size + j] = (sum + add_2) >> shift_2;
      }
    }
  }
}

static void transform_1d_odd_l4(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *o)
{
  int i;
  int length = size>>4;
  for (i=0;i<length;i++){
    o[i] = tr_matrix[8*size+i]*coeff[8*size+j];
  }
}
static void transform_1d_even_l4(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *out)
{
  int i;
  int length = size>>4;
  for (i=0;i<length;i++){
    out[i] = tr_matrix[0*size+i]*coeff[0*size+j];
  }
}
static void transform_1d_odd_l3(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *o)
{
  int i;
  int length = size>>3;
  for (i=0;i<length;i++){
    o[i] = tr_matrix[4*size+i]*coeff[4*size+j] + tr_matrix[12*size+i]*coeff[12*size+j];
  }
}
static void transform_1d_even_l3(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *out)
{
  int i;
  int length = size>>3;
  int e[4],o[4];
  transform_1d_odd_l4(coeff,tr_matrix,size,j,o);
  transform_1d_even_l4(coeff,tr_matrix,size,j,e);
  for (i=0;i<length/2;i++){
    out[i] = e[i] + o[i];
  }
  for (i=length/2;i<length;i++){
    out[i] = e[length-1-i] - o[length-1-i];
  }
}
static void transform_1d_odd_l2(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *o)
{
  int i;
  int length = size>>2;
  for (i=0;i<length;i++){
    o[i] = tr_matrix[2*size+i]*coeff[2*size+j] + tr_matrix[6*size+i]*coeff[6*size+j] + tr_matrix[10*size+i]*coeff[10*size+j] + tr_matrix[14*size+i]*coeff[14*size+j];          
  }
}
static void transform_1d_even_l2(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *out)
{
  int i;
  int length = size>>2;
  int e[8],o[8];
  transform_1d_odd_l3(coeff,tr_matrix,size,j,o);
  transform_1d_even_l3(coeff,tr_matrix,size,j,e);
  for (i=0;i<length/2;i++){
    out[i] = e[i] + o[i];
  }
  for (i=length/2;i<length;i++){
    out[i] = e[length-1-i] - o[length-1-i];
  }

}
static void transform_1d_odd_l1(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *o)
{
  int i;
  int length = size>>1;
  for (i=0;i<length;i++){
    o[i] = tr_matrix[ 1*size+i]*coeff[ 1*size+j] + tr_matrix[ 3*size+i]*coeff[ 3*size+j] + tr_matrix[ 5*size+i]*coeff[ 5*size+j] + tr_matrix[ 7*size+i]*coeff[ 7*size+j] +
           tr_matrix[ 9*size+i]*coeff[ 9*size+j] + tr_matrix[11*size+i]*coeff[11*size+j] + tr_matrix[13*size+i]*coeff[13*size+j] + tr_matrix[15*size+i]*coeff[15*size+j];          
  }
}
static void transform_1d_even_l1(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *out)
{
  int i;
  int length = size>>1;
  int e[16],o[16];
  transform_1d_odd_l2(coeff,tr_matrix,size,j,o);
  transform_1d_even_l2(coeff,tr_matrix,size,j,e);
  for (i=0;i<length/2;i++){
    out[i] = e[i] + o[i];
  }
  for (i=length/2;i<length;i++){
    out[i] = e[length-1-i] - o[length-1-i];
  }
}
static void transform_1d_even_l0(const int16_t *coeff, const int16_t *tr_matrix, int size, int j, int *out)
{
  int i;
  int length = size>>0;
  int e[32],o[32];
  assert(size >= 16);
  transform_1d_odd_l1(coeff,tr_matrix,size,j,o);
  transform_1d_even_l1(coeff,tr_matrix,size,j,e);
  for (i = 0; i < length/2; i++){
    out[i] = e[i] + o[i];
  }
  for (i = length/2; i < length; i++){
    out[i] = e[length-1-i] - o[length-1-i];
  }
}

static void inverse_transform_non_simd(const int16_t * coeff, int16_t *block, int size, int bitdepth)
{
  int i, j;
  int qsize = min(size, MAX_QUANT_SIZE);
  int out[MAX_TR_SIZE];
  int16_t tmp[MAX_TR_SIZE*MAX_TR_SIZE];
  int tr = log2i(size) - 2;
  const int16_t * tr_matrix = transform_table[tr];
  const int shift_1 = 7;
  const int add_1 = 1 << (shift_1 - 1);
  const int shift_2 = 20 - bitdepth;
  const int add_2 = 1 << (shift_2 - 1);

  /* 1st dimension */
  for (i = 0; i<qsize; i++) {
    if (size == 64) {
      /* Partial factorization */
      transform_1d_even_l0(coeff, tr_matrix, size, i, out);
    }
    else {
      /* Matrix multiplication */
      int k;
      for (j = 0; j<size; j++) {
        out[j] = 0;
        for (k = 0; k<qsize; k++) {
          out[j] += tr_matrix[k*size + j] * coeff[k*size + i];
        }
      }
    }
    for (j = 0; j<size; j++) {
      tmp[i*size + j] = clip((out[j] + add_1) >> shift_1, -32768, 32767);
    }
  }

  /* 2nd dimension */
  for (i = 0; i < size; i++) {
    if (size == 64) {
      /* Partial factorization */
      transform_1d_even_l0(tmp, tr_matrix, size, i, out);
    }
    else {
      /* Matrix multiplication */
      int k;
      for (j = 0; j < size; j++) {
        out[j] = 0;
        for (k = 0; k < qsize; k++) {
          out[j] += tr_matrix[k*size + j] * tmp[k*size + i];
        }
      }
    }
    for (j = 0; j < size; j++) {
      block[i*size + j] = clip((out[j] + add_2) >> shift_2, -32768, 32767);
    }
  }
}

void inverse_transform (const int16_t * coeff, int16_t *block, int size, int bitdepth)
{
  if (size < 64)
    (use_simd ? inverse_transform_simd : inverse_transform_non_simd)(coeff, block, size, bitdepth);
  else {
    /* Larger transforms are implemented as a 32x32 kernel followed by scale*scale duplication */
    int i, j, m, n, tmp, scale;
    int16_t *coeff2 = thor_alloc(2 * 32 * 32, 32);
    int16_t *block2 = thor_alloc(2 * 32 * 32, 32);
    for (i = 0; i < 32; i++) {
      memcpy(coeff2 + i * 32, coeff + i * size, 32 * sizeof(int16_t));
    }
    (use_simd ? inverse_transform_simd : inverse_transform_non_simd)(coeff2, block2, 32, bitdepth);

    scale = size / 32;
    for (i = 0; i < 32; i++) {
      for (j = 0; j < 32; j++) {
        tmp = block2[i * 32 + j];
        for (m = 0; m < scale; m++) {
          for (n = 0; n < scale; n++) {
            block[(scale * i + m) * size + scale * j + n] = tmp;
          }
        }
      }
    }
    thor_free(coeff2);
    thor_free(block2);
  }
}
